package br.com.view;

import java.util.Map;

import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.StackPane;
import br.com.beans.CPUList;
import br.com.beans.CartaoList;
import br.com.beans.NodeList;

public class Arvore extends StackPane {

	private TreeView<String> arvore;
	private TreeItem<String> ramoGeral;
	private TreeItem<String> ramoCPU;
	private TreeItem<String> ramoNode;
	private TreeItem<String> ramoCartao;
	private static StringProperty textoCPUselecionada = new SimpleStringProperty("cpu");
	private static StringProperty textoNodeSelecionado = new SimpleStringProperty("node");
	private static StringProperty textoCartaoSelecionado = new SimpleStringProperty(
			"cartão");
	private Map<String, String> tipoCPU;
	private Map<String, String> tipoNode;
	private Map<String, String> tipoCartao;
	private static CPUList cpuList;
	private String numeroNode;

	public Arvore() {

		if (cpuList == null) {
			cpuList = new CPUList();

			// Usando uma classe auxiliar para conseguir os nomes das CPU's do
			// projeto.
			tipoCPU = cpuList.getListaModeloCpus();

			// Criando o ramo geral na árvore principal
			ramoGeral = new TreeItem<String>("GERAL");
			ramoGeral.setExpanded(true);

			/*---------------------------------------------------------------------------------------*/

			// Criando os sub-ramos (nível 1) com o nome das cpus adquiridas
			for (String nomeCPU : tipoCPU.keySet()) {

				// Cada CPU na lista gera uma lista de dependentes que é
				// inserida como ramo no nível geral
				ramoCPU = this.getRamoCPU(nomeCPU);
				ramoGeral.getChildren().add(ramoCPU);

				// Criando os sub-ramos (nível 2) com o nome dos nós de cada CPU
				tipoNode = new NodeList(nomeCPU).getListaTipoNode();

				for (String numeroNode : tipoNode.keySet()) {
					this.numeroNode = numeroNode;
					// Cada Node na lista gera uma lista de dependentes que é
					// inserida como ramo no nível CPU
					ramoNode = this.getRamoNode(numeroNode);
					ramoCPU.getChildren().add(ramoNode);

					// Criando os sub-ramos (nível 3) com o nome dos cartões de
					// cada nó passando a CPU e o Node como argumento
					tipoCartao =
							new CartaoList(nomeCPU, Integer.parseInt(numeroNode))
									.getListaPosicaoCartoesString();
					for (String nomeCartao : tipoCartao.keySet()) {
						System.out.println("Arvore >> CPU: "
								+ nomeCPU + " Node: " + numeroNode + " Nº cartão: "
								+ nomeCartao);
						ramoCartao = this.getRamoCartao(nomeCartao);
						ramoNode.getChildren().add(ramoCartao);
					}
				}
			}

			/*---------------------------------------------------------------------------------------*/
			System.out
					.println("-----------------------------------------------------------");
		}

		// Criando a árvore, que aloca os ramos criados
		arvore = new TreeView<String>(ramoGeral);

		// Escolhendo o tipo de seleção para a árvore
		arvore.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);

		// Adicionando um listener para o item selecionado
		arvore.getSelectionModel().selectedItemProperty()
				.addListener(new ChangeListener<TreeItem<String>>() {

					@Override
					public void changed(
							ObservableValue<? extends TreeItem<String>> observable,
							TreeItem<String> oldValue, TreeItem<String> newValue) {

						if (newValue != null
								&& newValue.getParent() != null) {

							// Nível 0 - GERAL
							if (TreeView.getNodeLevel(newValue) == 0) {

								textoCPUselecionada.set("");
								textoNodeSelecionado.set("");
								textoCartaoSelecionado.set("");

							}

							// Nível 1 - CPU
							else if (TreeView.getNodeLevel(newValue) == 1) {
								textoCPUselecionada.set(newValue.getValue());
								textoNodeSelecionado.set("");
								textoCartaoSelecionado.set("");

							}

							// Nível 2 - Node
							else if (TreeView.getNodeLevel(newValue) == 2) {
								textoCPUselecionada.set(newValue.getParent().getValue());
								textoNodeSelecionado.set(newValue.getValue());
								textoCartaoSelecionado.set("");

							}

							// Nível 3 - Cartão
							else if (TreeView.getNodeLevel(newValue) == 3) {
								textoCartaoSelecionado.set("");

							}
							else {
								textoCPUselecionada.set("");
								textoNodeSelecionado.set("");
							}

							System.out.println("Arvore >> Nível:[ "
									+ TreeView.getNodeLevel(newValue) + " ] CPU:[ "
									+ textoCPUselecionada.getValue() + " ] Node: [ "
									+ textoNodeSelecionado.getValue() + " ] Cartão: [ "
									+ textoCartaoSelecionado.getValue() + " ]");

						}
						else {
							System.out.println("ArvoreCPU >> nulo");

						}

					}
				});

		this.getChildren().add(arvore);

	}

	public String getTextoCPUselecionada() {

		return textoCPUselecionada.get();
	}

	public StringProperty textoCPUselecionadaProperty() {
		return textoCPUselecionada;
	}

	public String getTextoNodeSelecionado() {

		return textoNodeSelecionado.get();
	}

	public StringProperty textoNodeSelecionadoProperty() {
		return textoNodeSelecionado;
	}

	public TreeView<String> getArvore() {
		return arvore;
	}

	public CPUList getCpu() {
		return cpuList;
	}

	// Método responsável por parametrizar o ramo nível 1
	private TreeItem<String> getRamoCPU(String nomeCPU) {
		Image iconCPU;
		// Inserindo os ícones de acordo com o modelo de CPU
		if (tipoCPU.get(nomeCPU).contains("PLC5")) {
			iconCPU = new Image("img/plc5.png");
		}
		else if (tipoCPU.get(nomeCPU).contains("SLC")) {
			iconCPU = new Image("img/slc.jpg");
		}
		else if (tipoCPU.get(nomeCPU).contains("CLX")) {
			iconCPU = new Image("img/clx.png");
		}
		else if (tipoCPU.get(nomeCPU).contains("CPU")) {
			iconCPU = new Image("img/omron.jpg");
		}
		else {
			iconCPU = new Image("img/question.png");
		}

		ImageView ivIconeCPU = new ImageView(iconCPU);
		ivIconeCPU.setFitHeight(30);
		ivIconeCPU.setFitWidth(30);

		ramoCPU = new TreeItem<String>();
		ramoCPU.setValue(nomeCPU);
		ramoCPU.setGraphic(ivIconeCPU);
		ramoCPU.setExpanded(false);

		return ramoCPU;
	}

	private TreeItem<String> getRamoNode(String numeroNode) {

		Image iconNode;
		ImageView ivIconeNode;

		if (tipoNode.get(numeroNode).contains("CNBR")) {

			iconNode = new Image("img/cnbr.png");
			ivIconeNode = new ImageView(iconNode);
			ivIconeNode.setFitHeight(25);
			ivIconeNode.setFitWidth(8);

		}
		else if (tipoNode.get(numeroNode).contains("ACNR")) {

			iconNode = new Image("img/acnr.png");
			ivIconeNode = new ImageView(iconNode);
			ivIconeNode.setFitHeight(20);
			ivIconeNode.setFitWidth(20);

		}
		else {

			iconNode = new Image("img/chip.png");
			ivIconeNode = new ImageView(iconNode);
			ivIconeNode.setFitHeight(20);
			ivIconeNode.setFitWidth(20);
		}

		ramoNode = new TreeItem<String>("Nó "
				+ numeroNode, ivIconeNode);
		ramoNode.setValue(numeroNode);
		ramoNode.setExpanded(true);
		return ramoNode;

	}

	private TreeItem<String> getRamoCartao(String nomeCartao) {

		Image iconCartao;
		ImageView ivIconeCartao;

		iconCartao = new Image("img/erro.jpg");
		ivIconeCartao = new ImageView(iconCartao);
		ivIconeCartao.setFitHeight(20);
		ivIconeCartao.setFitWidth(20);

		ramoCartao = new TreeItem<String>(nomeCartao, ivIconeCartao);
		ramoCartao.setValue(nomeCartao);
		ramoCartao.setExpanded(true);

		return ramoCartao;

	}

}
